﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

namespace mhxp
{
	internal class SBCS
	{
#if WIN64
		private const string DLL = "sbcs64.dll";
#else
		private const string DLL = "sbcs.dll";
#endif

		public static IntPtr HANDLE = IntPtr.Zero;

		public static bool Test
		{
			get
			{
				if (HANDLE != IntPtr.Zero)
					return true;
				else
				{
					HANDLE = LoadLibrary(DLL);
					return HANDLE != IntPtr.Zero;
				}
			}
		}

		public static byte[] ToFourCC(string s, bool isbigendian = false)
		{
			if (s.Length != 4)
			{
				// 아 이거 못쓰겠네
				return new byte[] { 0, 0, 0, 0 };
			}

			char[] c = s.ToCharArray();
			byte[] b = new byte[4];

			if (!isbigendian)
			{
				b[0] = (byte)c[0];
				b[1] = (byte)c[1];
				b[2] = (byte)c[2];
				b[3] = (byte)c[3];
			}
			else
			{
				b[0] = (byte)c[3];
				b[1] = (byte)c[2];
				b[2] = (byte)c[1];
				b[3] = (byte)c[0];
			}

			return b;
		}

		public static byte[] StructToBytes(object s)
		{
			int len = Marshal.SizeOf(s);
			IntPtr ptr = Marshal.AllocHGlobal(len);
			byte[] buf = new byte[len];

			Marshal.StructureToPtr(s, ptr, true);
			Marshal.Copy(ptr, buf, 0, len);

			Marshal.FreeHGlobal(ptr);

			return buf;
		}

		public static int ExtractNumber(string s)
		{
			Match m = Regex.Match(s, @"(\d+)");
			if (m == null)
				return 0;

			int v;
			if (!int.TryParse(m.Value, out v))
				return 0;

			return v;
		}

		public static byte[] ZCompress(byte[] data)
		{
			int len = data.Length;
			IntPtr src = Marshal.AllocHGlobal(len);
			Marshal.Copy(data, 0, src, len);

			IntPtr destsize = IntPtr.Zero;
			IntPtr ret = k_zcompress(src, (IntPtr)len, ref destsize);

			if (ret == IntPtr.Zero)
			{
				Marshal.FreeHGlobal(src);
				return null;

			}

			byte[] zbf = new byte[(int)destsize];
			Marshal.Copy(ret, zbf, 0, (int)destsize);

			k_free(ret);
			Marshal.FreeHGlobal(src);

			return zbf;
		}

		[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
		static extern IntPtr LoadLibrary(string lpFileName);

		[DllImport(DLL, CallingConvention = CallingConvention.Cdecl)]
		public static extern void k_init();
		[DllImport(DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		public static extern int k_strtoi(string s);
		[DllImport(DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		public static extern int k_strnatcasecmp(string left, string right);

		[DllImport(DLL, CallingConvention = CallingConvention.Cdecl)]
		public static extern void k_free(IntPtr mem);
		[DllImport(DLL, CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr k_zcompress(IntPtr src, IntPtr srcsize, ref IntPtr destsize);
	}
}
